<template>
  <CompOperate
      :field="field"
      :designer="designer"
      :design-state="designState"
      :parent-list="parentList"
      :parent-widget="parentWidget"
      :sub-form-row-id="subFormRowId"
      :sub-form-row-index="subFormRowIndex"
      :sub-form-col-index="subFormColIndex"
      :index-of-parent-list="indexOfParentList"
      :display-style="field.options.displayStyle"
  >
    <div class="scene-waiting-row-widget" :style="getStyle('view')">
      <div class="widget-inside" :style="getStyle('inside')">
        <div class="dept-room-register" :style="getStyle('dept')" v-if="optionsInfo['devDeptNameShown']">
          <ScrollX>{{ optionsInfo['devDeptName'] }}</ScrollX>
        </div>
        <div class="queue-group-wrap" :class="queueWrapClassName" ref="resize">
          <div v-for="(groupItem,groupKey) in queueChunkInfo"
               class="queue-first-group"
               :class="getTrendsClassName"
               :key="groupKey"
          >
            <template v-for="(item,key) in groupItem">
              <div
                  :key="key"
                  class="queue-info"
                  :class="queueClassName"
                  :style="getStyle('queueItem')"
              >
                <div
                    class="dept-doctor-info item"
                    :style="getStyle('queueName')"
                >
                  <div class="dept-info child-item" :key="`${widgetKey}_${key}`">
                    <ScrollX>{{ queueName(item) }}</ScrollX>
                  </div>
                  <div class="doctor-info child-item" :key="`${widgetKey}_${key}`" v-if="optionsInfo['queueDoctorShown']">
                    <ScrollX>{{ item.workerName }}</ScrollX>
                  </div>
                </div>
                <div class="current-patient item" :style="getStyle('currentPatient')" :key="`${widgetKey}_${key}`">
                  <ScrollX> {{ getCurrentPatient(item) }}</ScrollX>
                </div>
                <!--:key="`${widgetKey}_${key}`"-->
                <div class="wait-patient item" :ref="`waitPatient_${groupKey}`"
                     :data-info="`waitPatient_${groupKey}_${key}`">
                  <vueSeamlessScroll
                      class="scroll"
                      :key="updateWidgetKey"
                      :class="{'no-scroll':!scrollState(getPatientList(item) || [])}"
                      :hoverStop="false"
                      :data="getPatientList(item)"
                      @ScrollEnd="handleScrollEnd"
                      :class-option="patientScrollOption(getPatientList(item) || [])"
                      :ref="`scroll-${item.workerId}`"
                  >
                    <div class="inside-content">
                      <template v-if="!!(getPatientFillList(item)?.length)">
                        <template v-for="(patientItem,patientKey) in getPatientFillList(item)">
                          <div class="wait-patient-inside" :style="getStyle('waitPatient')" :key="patientKey">
                            <template v-for="(childItem,childKey) in  getPatientChildList(patientItem)">
                              <div
                                  v-if="true"
                                  class="child-item"
                                  :key="`${item.workerId}-${childKey}`"
                                  v-html="getPatientContent(childItem)"
                              />
                            </template>
                          </div>
                        </template>
                      </template>
                      <template v-else>
                        <div class="wait-patient-inside-empty"/>
                      </template>
                    </div>
                  </vueSeamlessScroll>
                </div>
              </div>
            </template>
          </div>
        </div>
      </div>
    </div>
  </CompOperate>
</template>

<script>
import {v4 as uuid} from 'uuid';
import {pxToVw} from "@/utils/common";
import emitter from "@/utils/designer/emitter";
import vueSeamlessScroll from 'vue-seamless-scroll';
import {buildParentApi} from "@/utils/designer/util";
import ScrollX from '@c/public/seamlessScroll/ScrollX.vue'
import mixin from "@sc/templateDetails/modules/homeMiddle/fieldMixin";
import CompOperate from "@c/public/form-designer/devType/modules/compOperate.vue";
import ResizeObserver from 'resize-observer-polyfill';

let buildParent = buildParentApi();
export default {
  name: "scene-waiting-row5-widget",

  componentName: "FieldWidget", //必须固定为FieldWidget，用于接收父级组件的broadcast事件

  mixins: [emitter, mixin],

  props: {
    widget: Object,
    field: Object,
    parentWidget: Object,
    parentList: Array,
    indexOfParentList: Number,
    designer: Object,
    designState: {
      type: Boolean,
      default: false,
    },
    devType: {
      type: Boolean,
      default: false,
    },
    subFormRowIndex: {
      /* 子表单组件行索引，从0开始计数 */ type: Number,
      default: -1,
    },
    subFormColIndex: {
      /* 子表单组件列索引，从0开始计数 */ type: Number,
      default: -1,
    },
    subFormRowId: {
      /* 子表单组件行Id，唯一id且不可变 */ type: String,
      default: "",
    },

    headTitle: {
      type: String,
      default: "",
    },
    visibleTitle: {
      type: Boolean,
    },
  },

  components: {
    ScrollX,
    CompOperate,
    vueSeamlessScroll
  },

  data() {
    return {
      widgetHeight: 0,
      widgetKey: uuid(),
      updateWidgetKey: uuid(),
      optionsInfo: Object(),
    }
  },

  computed: {
    // 设置的各元素的行内样式
    getStyle() {
      return function (val) {
        const self = this;
        let info = (self.optionsInfo) || Object();
        let Obj = Object();
        switch (val) {
          case "view":
            Reflect.set(Obj, "height", pxToVw(info.viewHeight));
            return Obj;
          case "inside":
            Reflect.set(Obj, "paddingTop", pxToVw(info.padding.top));
            Reflect.set(Obj, "paddingBottom", pxToVw(info.padding.bottom));
            return Obj;
          case "dept":
            Reflect.set(Obj, "background", (info?.devDeptNameBackground));
            Reflect.set(Obj, "fontSize", pxToVw(info?.devDeptNameFontSize));
            Reflect.set(Obj, "color", (info?.devDeptNameFontColor));
            Reflect.set(Obj, "fontWeight", (info?.devDeptNameFontWeight));
            return Obj;
          case "queueItem":
            let {marginRightLeft = 12} = info.queueGroupItem
            Reflect.set(Obj, "marginLeft", pxToVw(marginRightLeft));
            Reflect.set(Obj, "marginRight", pxToVw(marginRightLeft));
            return Obj;
          case "queueName":
            Reflect.set(Obj, "color", (info.queueNameFontColor));
            Reflect.set(Obj, "backgroundColor", (info.queueNameBackgroundColor));
            Reflect.set(Obj, "fontSize", pxToVw(info.queueNameFontSize));
            Reflect.set(Obj, "fontWeight", (info.queueNameFontWeight));
            return Obj;
          case "currentPatient":
            Reflect.set(Obj, "color", (info.currentPatientFontColor));
            Reflect.set(Obj, "backgroundColor", (info.currentPatientBackground));
            Reflect.set(Obj, "fontSize", pxToVw(info.currentPatientFontSize));
            Reflect.set(Obj, "fontWeight", (info.currentPatientFontWeight));
            return Obj;
          case "waitPatient":
            // 是否存在医生
            let {viewHeight, devDeptNameShown, patientViewHeight} = info;

            // 是否存在终端字段
            // let terminalHeight;
            // if (devDeptNameShown) {
            //   terminalHeight = viewHeight - 156 - 30 - 56;
            // } else {
            //   terminalHeight = viewHeight - 56;
            // }
            // if (!!(self.widgetHeight) || !!terminalHeight) {
            //   let patientHeight = info.queueDoctorShown ? 188 : 114;
            //   let queueHeight = (self.widgetHeight) || terminalHeight;
            //   let h = ((queueHeight - 24) / (info.viewRow)) - patientHeight - 104;
            //   Reflect.set(Obj, "height", pxToVw(h / info.viewNumber));
            //   Reflect.set(Obj, "lineHeight", pxToVw(h / info.viewNumber));
            // }

            if (info?.patientDivider) {
              Reflect.set(Obj, "borderColor", 'rgba(51, 51, 51, 0.2)');
            } else {
              Reflect.set(Obj, "borderColor", 'transparent');
            }

            Reflect.set(Obj, "height", pxToVw(patientViewHeight));
            Reflect.set(Obj, "lineHeight", pxToVw(patientViewHeight));

            Reflect.set(Obj, "fontSize", pxToVw(info.patientFontSize));
            Reflect.set(Obj, "fontWeight", (info.patientFontWeight));
            return Obj;
        }
      };
    },

    // 动态className
    getTrendsClassName() {
      let {viewRow = 2} = this.optionsInfo;
      switch (viewRow) {
        case 0:
          return 'queue-first-group-0'
        case 1:
          return 'queue-first-group-1'
        case 2:
          return 'queue-first-group-2'
        case 3:
          return 'queue-first-group-3'
      }
    },

    // 群组名字ClassName
    queueClassName() {
      let {queueDoctorShown} = this.optionsInfo;
      return queueDoctorShown ? 'queue-doctor-info' : 'queue-doctor-hiddle-info'
    },

    queueWrapClassName() {
      let {devDeptNameShown} = this.optionsInfo;
      return devDeptNameShown ? 'queue-group-wrap' : 'queue-group-hiddle-dept-wrap'
    },

    // 患者的滚动
    patientScrollOption() {
      return function (row) {
        let {steps, scrollNumber} = this.optionsInfo.patientScrollInfo;
        let scrollInfo = this.scrollState(row)
        return {
          step: [1, 1.5, 2, 2.5, 3][steps - 1], // 数值越大速度滚动越快
          hoverStop: true,
          direction: 1, // 0向下 1向上 2向左 3向右
          // 开始无缝滚动的数据量 this.dataList.length
          limitMoveNum: scrollInfo ? scrollNumber : 99999,
        };
      }
    },

    scrollState() {
      return function (row) {
        let {viewNumber} = this.optionsInfo;
        let {state, scrollNumber} = this.optionsInfo.patientScrollInfo;
        return state && (row?.length >= viewNumber) && (row?.length >= scrollNumber) && true
      }
    },

    // 获取队列名的显示字段
    queueName() {
      return function (row) {
        let {
          queueName,
          deptNameKey = 'deptName',
          roomNameKey = 'treatmentRoomName',
          registerNameKey = 'registerObjName'
        } = this.optionsInfo;
        switch (queueName) {
          case 'deptName':
            return row[deptNameKey] || row['deptName'] || '\u00a0'
          case 'roomNo':
            return row['treatmentRoomNumber'] || row['deptName']
          case 'roomName':
            return row[roomNameKey ] || row['treatmentRoomName'] || '\u00a0'
          case 'registerName':
            return row[registerNameKey] || row['registerObjName'] || '\u00a0'
        }
      }
    },

    // 队列的患者信息
    queueChunkInfo() {
      let sliceArr = Array()
      let devType = (this.devType);
      let {showRowNums, viewCol} = (this.optionsInfo);
      let queuePatientList = this.$store.getters['getWaitingPatientInfo'];
      let queueInfo = devType ? (queuePatientList.apiData) : (queuePatientList.mockData);
      if (queueInfo?.length > showRowNums) {
        sliceArr = queueInfo.slice(0, showRowNums);
      } else {
        let fillArr = (new Array(showRowNums - queueInfo?.length).fill({}));
        sliceArr = [...queueInfo, ...fillArr];
      }
      return this.$lodash.chunk(sliceArr, viewCol);
    },

    // 当前就诊的患者 || 医生暂停接诊
    getCurrentPatient() {
      return function (row) {
        /**
         * 在线状态 0在线 1暂停 2退出
         **/
        const self = this;
        let type = parseInt(row.onlineStatus);
        switch (type) {
          case 0:
          case 2:
            if (!!(row?.treatingPatient?.length)) {
              let currentPatient = Array();
              (row.treatingPatient).forEach((item) => {
                let orderNo = item?.orderNo;
                let patientOrderNoInfo = '';
                if (!!orderNo) {
                  patientOrderNoInfo = `${(item.orderNo) || '\u00a0'}`;
                }
                let temp = `${patientOrderNoInfo} ${(item.patientName) || '\u00a0'}`
                currentPatient.push(temp)
              })
              return (self.$lodash.join(currentPatient, ' '));
            } else {
              return '\u00a0'
            }
          case 1:
            return '暂停接诊';
        }
      }
    },

    // 合并:候诊&就诊(原始数据)
    getPatientList() {
      return function (row) {
        let {showCurrentPatient = 2} = this.optionsInfo;
        let currentPatient = row?.treatingPatient || []
        let waitPatient = row?.waitPatientList || [];
        if (showCurrentPatient === 2) {
          return [...currentPatient, ...waitPatient]
        } else {
          return [...waitPatient]
        }
      }
    },

    // 合并当前队列的候诊就诊患者并填充数据
    getPatientFillList() {
      return function (row) {
        let listInfo;
        let {viewNumber = 4, viewRowNumber = 1} = this.optionsInfo;
        let mergePatient = this.getPatientList(row);
        if (mergePatient?.length) {
          let length = mergePatient?.length;
          if (length >= viewNumber) {
            listInfo = mergePatient
          } else {
            let fillArr = Array(viewNumber - length).fill({});
            listInfo = [...mergePatient, ...fillArr]
          }
        } else {
          listInfo = Array(viewNumber).fill({});
        }
        return this.$lodash.chunk(listInfo, viewRowNumber)
      }
    },

    // 二级分类列表
    getPatientChildList() {
      return function (row) {
        let {viewRowNumber = 1} = this.optionsInfo;
        let length = row?.length;
        if (length >= viewRowNumber) {
          return row
        } else {
          let fillArr = Array(viewRowNumber - length).fill({});
          return [...row, ...fillArr]
        }
      }
    },

    //候诊患者信息
    getPatientContent() {
      return function (row) {
        let orderNoInfo;
        let {orderTag, showRoomName, patientRoomNameKey, roomNamePosition = 'right'} = this.optionsInfo;
        if (orderTag && (row?.orderTagColor)) {
          orderNoInfo = (row.orderNo) ?
              `<span style='color:${row?.orderTagColor || 'transparent'}'>${row?.orderPrefix || '\u00a0'}</span>${row?.orderNumber || '\u00a0'}` : ''
        } else {
          orderNoInfo = `${row?.orderNo || '\u00a0'}`
        }
        // 1: 无诊室 2:诊室
        switch (showRoomName) {
          case 1:
            if (!!this.$lodash.trim(orderNoInfo)) {
              return `${orderNoInfo} ${row?.patientName || '\u00a0'}`
            } else {
              return `${row?.patientName || '\u00a0'}`
            }
          case 2:
            let patientInfo;
            if (!!this.$lodash.trim(orderNoInfo)) {
              patientInfo = `${orderNoInfo} ${row?.patientName || '\u00a0'}`
            } else {
              patientInfo = `${row?.patientName || '\u00a0'}`
            }
            if (roomNamePosition === 'right') {
              return `${patientInfo || '\u00a0'} ${row[patientRoomNameKey || 'treatmentRoomName'] || '\u00a0'}`
            } else {
              return `${row[patientRoomNameKey || 'treatmentRoomName'] || '\u00a0'} ${patientInfo || '\u00a0'}`
            }
        }
      }
    },
  },

  mounted() {

  },

  methods: {
    // 接收父组件传递过来的数据
    executeMethod(key, data) {
      switch (key) {
        case "patientListInfo":
          this.widgetKey = uuid();
          let patientList = this.$lodash.cloneDeep(data);
          this.$store.dispatch('setWaitingPatientInfo', patientList)
          break
      }
    },

    // 等待候诊滚动结束
    handleScrollEnd() {
      console.log('等待就诊滚动结束');
    },

    // 监听视图变化
    observeResizeObserver() {
      let number;
      const self = this;
      const element = self.$refs?.resize;
      if (!!element) {
        const observer = new ResizeObserver(entries => {
          entries.forEach(entry => {
            const {height} = entry.contentRect;
            if (!!height && (number !== height)) {
              number = height;
              self.widgetKey = uuid();
            }
          });
        });
        observer.observe(element[0]);
        // 销毁时移除监听
        this.$once('hook:beforeDestroy', () => {
          observer.disconnect();
        });
      }

    }
  },

  watch: {
    field: {
      handler: function (val) {
        this.widgetKey = uuid();
        this.updateWidgetKey = uuid();
        let key = (val.options.config);
        this.optionsInfo = val.options[key];
      },
      deep: true,
      immediate: true
    },
  },

  destroyed() {
    this.unregisterFromRefList();
  },

};
</script>

<style lang="scss" scoped>
.scene-waiting-row-widget {
  color: #333333;
  display: flex;
  flex-direction: row;
  align-self: center;
  align-items: center;
  width: 100%;
  overflow: hidden;
  background-color: transparent;
  box-sizing: border-box;

  .widget-inside {
    display: flex;
    flex-direction: column;
    width: 100%;
    height: 100%;
    padding: 28px 30px;
    box-sizing: border-box;
  }
}

.dept-room-register {
  width: 100%;
  line-height: 156px;
  height: 156px;
  background: #0059B3;
  border-radius: 18px;
  color: white;
  text-align: center;
  font-size: 100px;
  padding: 0 30px;
  margin-bottom: 30px;
  overflow: hidden;
  box-sizing: border-box;
}

.queue-group-wrap {
  overflow: hidden;
  height: calc(100% - 156px - 30px);

  .queue-first-group {
    display: flex;
    flex-direction: row;
    flex: 1;
    margin-bottom: 24px;
    font-size: 40px;
    overflow: hidden;
    box-sizing: border-box;

    &:last-child {
      margin-bottom: 0;
    }

    .queue-first-group-wrap {
      width: 100%;
      height: 100%;
    }

    .queue-info {
      display: flex;
      flex-direction: column;
      flex-basis: 0;
      flex-shrink: 0;
      flex-grow: 1;
      background: #E8E8E8;
      margin: 0 12px;
      border-radius: 16px;
      overflow: hidden;
      box-sizing: border-box;
      position: relative;
      z-index: 9;

      &:first-child {
        margin-left: 0 !important;
      }

      &:last-child {
        margin-right: 0 !important;
      }

      .item {
        width: 100%;
        color: #E8E8E8;
        font-size: 54px;
        padding: 0 20px;
        overflow: hidden;
        box-sizing: border-box;
        text-align: center;
      }

      .dept-doctor-info {
        height: 114px;
        overflow: hidden;
        background: #0059B3;
      }

      .current-patient {
        height: 104px;
        color: white;
        line-height: 104px;
        overflow: hidden;
        background: rgba(51, 122, 194, 1);
      }

      .wait-patient {
        color: #333333;
        background: transparent;
        overflow: hidden;
        padding: 0 !important;
        box-sizing: border-box;
        height: calc(100% - 114px - 104px);

        // 不滚动
        .no-scroll .wait-patient-inside {
          &:last-child {
            border-bottom: none !important;
          }
        }

        .inside-content {
          background: transparent;
        }

        .wait-patient-inside {
          background: white;
          padding: 0 20px;
          box-sizing: border-box;
          border-bottom: 6px rgba(229, 234, 239, 0.8) solid;
        }
      }
    }

    //科室&医生
    .queue-doctor-info {
      .dept-doctor-info {
        height: 188px;
        padding: 0;
        overflow: hidden;
        box-sizing: border-box;

        .child-item {
          height: calc(100% / 2);
          line-height: 94px;
          overflow: hidden;
          box-sizing: border-box;
          white-space: nowrap;
          padding: 0 20px;
        }

        .doctor-info {
          box-sizing: border-box;
          border-top: 1px white solid;
        }
      }

      .wait-patient {
        height: calc(100% - 188px - 104px);
        overflow: hidden;
        background: white;
      }
    }

    //科室&无医生
    .queue-doctor-hiddle-info {
      .dept-doctor-info {
        height: 114px;
        overflow: hidden;

        .child-item {
          height: calc(100% / 1);
          line-height: 114px;
          white-space: nowrap;
          overflow: hidden;
        }
      }

      .wait-patient {
        height: calc(100% - 114px - 104px);
        overflow: hidden;
      }
    }
  }

  .queue-first-group-1 {
    min-height: calc(100% / 1);
    max-height: calc(100% / 1);
  }

  .queue-first-group-2 {
    min-height: calc(calc(100% - 24px) / 2);
    max-height: calc(calc(100% - 24px) / 2);
  }
}

//隐藏科室
.queue-group-hiddle-dept-wrap {
  height: calc(100%);
}
</style>